package com.yuyou.fn.educational.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.yuyou.fn.common.constant.JobNatureEnum;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.mapper.ClassQuestionnaireRecordMapper;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.ClassQuestionSaveVo;
import com.yuyou.fn.educational.vo.QuestionnaireRecordDetail;
import com.yuyou.fn.educational.vo.QuestionnaireRecordQueryVo;
import com.yuyou.fn.educational.vo.QuestionnaireRecordSaveVo;
import com.yuyou.fn.platform.permission.DataPermission;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 *
 * ClassQuestionnaireRecord 表数据服务层接口实现类
 *
 */
@Service
public class ClassQuestionnaireRecordServiceImpl extends SuperServiceImpl<ClassQuestionnaireRecordMapper, ClassQuestionnaireRecord,Long> implements IClassQuestionnaireRecordService {
    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IQuestionnaireService questionnaireService;

    @Resource
    private IQuestionnaireQuestionService questionnaireQuestionService;

    @Resource
    private IClassQuestionScoreService classQuestionScoreService;

    @Resource
    private ISiteConfigService siteConfigService;

    @Resource
    private IClassExpandDetailService classExpandDetailService;

    @Resource
    private ITeacherService teacherService;

    @Override
    @Transactional
    public void saveRecord(QuestionnaireRecordSaveVo questionnaireRecordSaveVo, List<ClassQuestionSaveVo> classQuestionSaveVoList) {
        if (questionnaireRecordSaveVo.getClassId()==null ){
            throw new BusException("请选择具体班级录入");
        }
        if (questionnaireRecordSaveVo.getTotalNum()==null || questionnaireRecordSaveVo.getTotalNum()==0 ){
            throw new BusException("总份数不可为空或0");
        }
        if (classQuestionSaveVoList==null || classQuestionSaveVoList.size()==0){
            throw new BusException("请传入具体信息");
        }
        if (questionnaireRecordSaveVo.getQuestionnaireId()==null ){
            throw new BusException("问卷id必传");
        }
        ClassQuestionnaireRecord check=this.findEffectiveByClassId(questionnaireRecordSaveVo.getClassId());
        if (check!=null){
            throw new BusException("当前班级已存在调研问卷，不允许再次录入！");
        }

        Integer optimalTotal=0;
        Integer recordTotal=0;
        Questionnaire questionnaire=questionnaireService.findById(questionnaireRecordSaveVo.getQuestionnaireId());
        List<QuestionnaireQuestion> questionnaireQuestionList=questionnaireQuestionService.findListByQuestionnaireId(questionnaireRecordSaveVo.getQuestionnaireId());
        Map<Long,QuestionnaireQuestion> map=BeanUtils.toMap(questionnaireQuestionList,"questionnaireQuestionId");

        Principals.Principal principal=Principals.get();
        CourseClass courseClass=courseClassService.findById(questionnaireRecordSaveVo.getClassId());

        classExpandDetailService.updateClassState(Arrays.asList(courseClass.getClassId()),null,1,null,null);




        if (questionnaireRecordSaveVo.getTotalNum()>courseClass.getRegAmount()){
            throw new BusException("调研问卷份数不能大于本班人数（应该小于或等于）");
        }

        ClassQuestionnaireRecord classQuestionnaireRecord=new ClassQuestionnaireRecord();
        classQuestionnaireRecord.setClassQuestionnaireRecordId(IdWorker.getId());
        BeanUtils.copyProperties(classQuestionnaireRecord,questionnaireRecordSaveVo);
        BeanUtils.copyProperties(classQuestionnaireRecord,courseClass);
        classQuestionnaireRecord.setCreateTime(TimeUtils.now());
        classQuestionnaireRecord.setUpdateTime(TimeUtils.now());
        classQuestionnaireRecord.setOperatorId(principal.id);
        classQuestionnaireRecord.setOperatorName(principal.name);
        classQuestionnaireRecord.setStatus(1);
        Double allScore=0d;
        List<ClassQuestionScore> classQuestionScoreList=new ArrayList<>(classQuestionSaveVoList.size());
        for (ClassQuestionSaveVo classQuestionSaveVo:classQuestionSaveVoList){
            QuestionnaireQuestion questionnaireQuestion=map.get(classQuestionSaveVo.getQuestionnaireQuestionId());
            if (questionnaireQuestion==null){
                throw new BusException("查不到该题编号为"+questionnaireQuestion.getQuestionnaireQuestionNo()+"信息,可能问卷信息发生变动");
            }
            if (classQuestionSaveVo.getOptimalNum()==null){
                classQuestionSaveVo.setOptimalNum(0);
            }
            if (classQuestionSaveVo.getGoodNum()==null){
                classQuestionSaveVo.setGoodNum(0);
            }
            if (classQuestionSaveVo.getMidNum()==null){
                classQuestionSaveVo.setMidNum(0);
            }
            if (classQuestionSaveVo.getBadNum()==null){
                classQuestionSaveVo.setBadNum(0);
            }
            if (classQuestionSaveVo.getBadNum()+classQuestionSaveVo.getMidNum()+classQuestionSaveVo.getGoodNum()+classQuestionSaveVo.getOptimalNum()!=questionnaireRecordSaveVo.getTotalNum()){
                throw new BusException("编号为"+questionnaireQuestion.getQuestionnaireQuestionNo()+"录入的份数必须等于总份数");
            }
            ClassQuestionScore classQuestionScore=new ClassQuestionScore();
            BeanUtils.copyProperties(classQuestionScore,classQuestionSaveVo);
            BeanUtils.copyProperties(classQuestionScore,questionnaireQuestion);
            optimalTotal=optimalTotal+classQuestionSaveVo.getOptimalNum();
            recordTotal=recordTotal+classQuestionSaveVo.getOptimalNum()+classQuestionSaveVo.getGoodNum()+classQuestionSaveVo.getMidNum()+classQuestionSaveVo.getBadNum();
            classQuestionScore.setOptimalScore(questionnaireQuestion.getScore()*classQuestionScore.getOptimalNum()*questionnaire.getOptimalWeight()/100);
            classQuestionScore.setGoodScore(questionnaireQuestion.getScore()*classQuestionScore.getGoodNum()*questionnaire.getGoodWeight()/100);
            classQuestionScore.setMidScore(questionnaireQuestion.getScore()*classQuestionScore.getMidNum()*questionnaire.getMidWeight()/100);
            classQuestionScore.setBadScore(questionnaireQuestion.getScore()*classQuestionScore.getBadNum()*questionnaire.getBadWeight()/100);
            Double totalQuestionScore=classQuestionScore.getOptimalScore()+classQuestionScore.getGoodScore()+classQuestionScore.getMidScore()+classQuestionScore.getBadScore();
            classQuestionScore.setQuestionScore(totalQuestionScore/questionnaireRecordSaveVo.getTotalNum());
            classQuestionScore.setClassQuestionnaireRecordId(classQuestionnaireRecord.getClassQuestionnaireRecordId());
            classQuestionScore.setClassId(questionnaireRecordSaveVo.getClassId());
            classQuestionScoreList.add(classQuestionScore);
            allScore=allScore+totalQuestionScore;
        }
        if (classQuestionScoreList.size()>0){
            classQuestionScoreService.insertBatch(classQuestionScoreList);
        }
        DecimalFormat df   = new DecimalFormat("######0.00");
        classQuestionnaireRecord.setRegNum(courseClass.getRegAmount());
        classQuestionnaireRecord.setTotalScore(Double.parseDouble(df.format(allScore.doubleValue()))/classQuestionnaireRecord.getTotalNum());


        if (recordTotal!=0){
            classQuestionnaireRecord.setPreferentialRate(Utils.roundByDouble(optimalTotal/(double)recordTotal,4));
        }
        this.insert(classQuestionnaireRecord);
    }

    @Override
    @Transactional
    public void invalidDetail(Long classQuestionnaireRecordId) {
        if (classQuestionnaireRecordId==null){
            throw new  NullPointerException();
        }
        ClassQuestionnaireRecord record=this.findById(classQuestionnaireRecordId);

        ClassQuestionnaireRecord classQuestionnaireRecord=new ClassQuestionnaireRecord();
        classQuestionnaireRecord.setClassQuestionnaireRecordId(classQuestionnaireRecordId);
        classQuestionnaireRecord.setStatus(0);
        this.updateSelectiveById(classQuestionnaireRecord);


        classExpandDetailService.updateClassState(Arrays.asList(record.getClassId()),null,0,null,null);
     /*   ClassExpandDetail classExpandDetail=classExpandDetailService.findById(record.getClassId());
        ClassExpandDetail saveOrUpdate=new ClassExpandDetail();
        saveOrUpdate.setClassId(record.getClassId());
        saveOrUpdate.setIntoState(0);
        saveOrUpdate.setUpdateTime(TimeUtils.now());
        if (classExpandDetail==null){
            saveOrUpdate.setCreateTime(TimeUtils.now());
            classExpandDetailService.insert(saveOrUpdate);
        }else if (classExpandDetail.getIntoState()==1){
            classExpandDetailService.updateSelectiveById(saveOrUpdate);
        }*/

    }

    @Override
    public ClassQuestionnaireRecord findEffectiveByClassId(Long classId) {
        Example<ClassQuestionnaireRecord> example=ClassQuestionnaireRecord.createExample();
        example.createCriteria().andEqualTo("classId",classId).andEqualTo("status",1);
        return this.findOneByExample(example);
    }



/*    @Override
    public Page<ClassExpandDetailVo> findClassExpandDetail(ClassExpandQueryVo classExpandQueryVo,CourseClassQueryVo courseClassQueryVo, DataPermission dataPermission, int pageNo, int pageSize) {
        if (courseClassQueryVo.getAreaTeamId()==null){
            throw new BusException("区域id必传");
        }
        Page<ClassExpandDetailVo> page=new Page<>(pageNo,pageSize);
        if (pageNo==0){
            pageNo=1;
        }
        List<ClassExpandDetailVo> classExpandDetailVoList=classExpandDetailService.findClassExpandDetail(classExpandQueryVo,courseClassQueryVo,dataPermission.getBusTeamIds(),(pageNo-1)*pageSize,pageSize);
        Integer total=classExpandDetailService.countClassExpandDetail(classExpandQueryVo,courseClassQueryVo,dataPermission.getBusTeamIds());
        page.setTotal(total);
        page.setRecords(classExpandDetailVoList);
        return page;
    }*/

/*
    @Override
    public SXSSFWorkbook exportClassExpandDetail(ClassExpandQueryVo classExpandQueryVo,CourseClassQueryVo courseClassQueryVo, DataPermission dataPermission) {

        Page<ClassExpandDetailVo> page = this.findClassExpandDetail(classExpandQueryVo,courseClassQueryVo ,dataPermission , 1, 20000);

        List<ClassExpandDetailVo> list=page.getRecords();

        return classExpandDetail2Excel(list);
    }*/




    @Override
    public Page<ClassQuestionnaireRecord> findRecordByQueryVo(DataPermission dataPermission, QuestionnaireRecordQueryVo questionnaireRecordQueryVo, int pageNo, int pageSize) {
        String headCoefficientRule=siteConfigService.getConfigValueFromCache("head_coefficient_rule");
        Example<ClassQuestionnaireRecord> example=ClassQuestionnaireRecord.createExample();
        Example.Criteria criteria=example.createCriteria();
        CriteriaUtils.fillCondition(criteria,questionnaireRecordQueryVo);
        CriteriaUtils.fillConditionForBusPermission(criteria,dataPermission.getBusTeamIds());
        example.orderBy("createTime").desc();

        Page<ClassQuestionnaireRecord> page=this.findPageByExample(example,pageNo,pageSize);
        List<ClassQuestionnaireRecord> classQuestionnaireRecordList=page.getRecords();
        if (classQuestionnaireRecordList!=null && StringUtils.isNotEmpty(headCoefficientRule)){
            try{

                Binding binding = new Binding();
                for (ClassQuestionnaireRecord classQuestionnaireRecord:classQuestionnaireRecordList){
                    Double regNum=classQuestionnaireRecord.getTotalNum().doubleValue();
                    if (classQuestionnaireRecord.getGradeId()==33L){
                        regNum=regNum*28/18;
                        regNum=Utils.roundByDouble(regNum,2);
                    }

                    binding.setVariable("regNum",regNum);
                    GroovyShell shell = new GroovyShell(binding);
                    Object F1 =shell.evaluate(headCoefficientRule);
                    Double headCoefficient=Utils.roundByDouble(Double.parseDouble(F1.toString()),2);
                    classQuestionnaireRecord.setHeadCoefficient(headCoefficient);
                    Double headCoefficientScore=Utils.roundByDouble(classQuestionnaireRecord.getTotalScore()*classQuestionnaireRecord.getHeadCoefficient(),2);
                /*最终得分（人头系数分）如果出现大于 该问卷的满分，就只取满分的分数*/
                    if (headCoefficientScore>classQuestionnaireRecord.getTotalScore()){
                        headCoefficientScore = classQuestionnaireRecord.getTotalScore().doubleValue();
                    }
                    classQuestionnaireRecord.setHeadCoefficientScore(headCoefficientScore);
                }
            }catch (Exception e){
                throw new BusException("计算人头系数发生异常，请检查配置");
            }

        }

        return page;
    }

    @Override
    public QuestionnaireRecordDetail findDetailById(Long classQuestionnaireRecordId) {
        QuestionnaireRecordDetail questionnaireRecordDetail=new QuestionnaireRecordDetail();
        questionnaireRecordDetail.setClassQuestionnaireRecord(this.findById(classQuestionnaireRecordId));
        questionnaireRecordDetail.setClassQuestionScoreList(classQuestionScoreService.findListByRecordId(classQuestionnaireRecordId));
        return questionnaireRecordDetail;
    }

    @Override
    public SXSSFWorkbook exportQuestionnaireRecord(DataPermission dataPermission,QuestionnaireRecordQueryVo questionnaireRecordQueryVo) {

        Page<ClassQuestionnaireRecord> classQuestionnaireRecordPage = this.findRecordByQueryVo(dataPermission,questionnaireRecordQueryVo, 1, 10000);
        List<ClassQuestionnaireRecord> list=classQuestionnaireRecordPage.getRecords();
        List<Long> classQuestionnaireRecordIds=BeanUtils.toList(list,"classQuestionnaireRecordId");
        List<ClassQuestionScore> classQuestionScoreList=classQuestionScoreService.findListByRecordIds(classQuestionnaireRecordIds);
        List<Long> teacherIds=Utils.removeDuplicate(BeanUtils.toList(list,"teacherId"));
        List<Teacher> teacherList=teacherService.findByIds(teacherIds);
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");
        return questionnaireRecord2Excel(list,classQuestionScoreList,teacherMap);
    }

    @Override
    public SXSSFWorkbook exportQuestionnaireRecordDetail(Long classQuestionnaireRecordId) {
        ClassQuestionnaireRecord classQuestionnaireRecord=this.findById(classQuestionnaireRecordId);
        List<ClassQuestionScore> classQuestionScoreList=classQuestionScoreService.findListByRecordId(classQuestionnaireRecordId);

        return questionnaireRecordDetail2Excel(classQuestionnaireRecord,classQuestionScoreList);
    }

    public static SXSSFWorkbook questionnaireRecordDetail2Excel(ClassQuestionnaireRecord classQuestionnaireRecord,List<ClassQuestionScore> classQuestionScoreList){
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("班级分数详情");
        String[] titles = new String[]{"题目", "优", "良", "中", "差","本题得分"};
        String firstRowMsg="期数:"+classQuestionnaireRecord.getPeriodName()+"; 班级:"+classQuestionnaireRecord.getClassName()+"; 校区:"+classQuestionnaireRecord.getCampusName()+
                            "; 学科:"+classQuestionnaireRecord.getSubjectName()+"; 年级:"+classQuestionnaireRecord.getGradeName()+"; 调查问卷份数:"+classQuestionnaireRecord.getTotalNum()+";总分:"+classQuestionnaireRecord.getTotalScore()+
                            "; 人头系数:"+classQuestionnaireRecord.getHeadCoefficient()+"; 最终得分"+classQuestionnaireRecord.getHeadCoefficientScore();

        SXSSFRow firstRow = sheet.createRow(0);
        firstRow.createCell(0).setCellValue(firstRowMsg);
        sheet.addMergedRegion(new CellRangeAddress(0,0,0,titles.length-1));

        SXSSFRow secondRow = sheet.createRow(1);

        for (int i = 0; i < titles.length; i++) {
            secondRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=2;
        if (classQuestionScoreList!=null){
            for (ClassQuestionScore classQuestionScore:classQuestionScoreList){
                int cellNum=0;
                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionScore.getContent());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionScore.getOptimalNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionScore.getGoodNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionScore.getMidNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionScore.getBadNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionScore.getQuestionScore());


            }
        }
        return excel;
    }

    public static SXSSFWorkbook questionnaireRecord2Excel(List<ClassQuestionnaireRecord> classQuestionnaireRecordList, List<ClassQuestionScore> classQuestionScoreList,Map<Long,Teacher> teacherMap){
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("班级分数列表");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域", "期数", "班级编号","班级名称", "校区","段次", "学科", "年级","报名人数", "教师","任教属性","调查问卷份数","总分","人头系数","人头系数分","选优率","录入人","录入时间","状态"};
        Map<Long,List<ClassQuestionScore>> map=BeanUtils.toGroup(classQuestionScoreList,"classQuestionnaireRecordId");
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }


        int maxQuestionNum=0;

        int rowNum=1;
        if (classQuestionnaireRecordList!=null){
            for (ClassQuestionnaireRecord classQuestionnaireRecord:classQuestionnaireRecordList){
                int cellNum=0;
                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getAreaTeamName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getPeriodName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getClassNo());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getClassName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getCampusName()==null?"":classQuestionnaireRecord.getCampusName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getSegmentNo()==null?"":classQuestionnaireRecord.getSegmentNo().toString());


                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getSubjectName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getGradeName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getRegNum()==null?0:classQuestionnaireRecord.getRegNum());
                String teacherName="";
                Integer jobNature=null;
                Teacher teacher=teacherMap.get(classQuestionnaireRecord.getTeacherId());
                if (null!=teacher){
                    teacherName=teacher.getTeacherName();
                    jobNature=teacher.getJobNature();
                }

                cell = row.createCell(cellNum++);
                cell.setCellValue(teacherName);

                cell = row.createCell(cellNum++);
                cell.setCellValue(EnumUtils.getName(JobNatureEnum.values() ,jobNature));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getTotalNum()==null?0:classQuestionnaireRecord.getTotalNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getTotalScore());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getHeadCoefficient()==null?0:classQuestionnaireRecord.getHeadCoefficient());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getHeadCoefficientScore()==null?0:classQuestionnaireRecord.getHeadCoefficientScore());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getPreferentialRate()==null?"0.00%":String.format("%.2f",classQuestionnaireRecord.getPreferentialRate()*100)+"%");

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classQuestionnaireRecord.getOperatorName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getCreateTime() == null ? StringUtils.EMPTY : Utils.formatDate(classQuestionnaireRecord.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classQuestionnaireRecord.getStatus() == 1 ? "正常" : "作废");

                List<ClassQuestionScore> oneClassQuestionScoreList=map.get(classQuestionnaireRecord.getClassQuestionnaireRecordId());
                if (oneClassQuestionScoreList!=null){
                    maxQuestionNum=maxQuestionNum<oneClassQuestionScoreList.size()?oneClassQuestionScoreList.size():maxQuestionNum;
                    for (ClassQuestionScore classQuestionScore:oneClassQuestionScoreList){
                        cell = row.createCell(cellNum++);
                        cell.setCellValue(classQuestionScore.getQuestionScore());

                        cell = row.createCell(cellNum++);
                        cell.setCellValue(classQuestionScore.getOptimalNum());

                        cell = row.createCell(cellNum++);
                        cell.setCellValue(classQuestionScore.getGoodNum());

                        cell = row.createCell(cellNum++);
                        cell.setCellValue(classQuestionScore.getMidNum());

                        cell = row.createCell(cellNum++);
                        cell.setCellValue(classQuestionScore.getBadNum());
                    }
                }


            }
            int begin=titles.length;
            for (int i=1;i<=maxQuestionNum;i++){
                firstRow.createCell(begin++).setCellValue("第"+i+"题分数");
                firstRow.createCell(begin++).setCellValue("优");
                firstRow.createCell(begin++).setCellValue("良");
                firstRow.createCell(begin++).setCellValue("中");
                firstRow.createCell(begin++).setCellValue("差");
            }
        }
        return excel;
    }



}